#include "ColorMaterial.h"
#include "PerlinNoiseTexture.h"
#define STB_PERLIN_IMPLEMENTATION
#include "stb_perlin.h"

inline PerlinNoiseTexture::PerlinNoiseTexture(shared_ptr<Material> black, shared_ptr<Material> white, const Vector3 & scale) : black(black), white(white) {
	this->scale = scale;
}

inline PerlinNoiseTexture::PerlinNoiseTexture(const Vector3 & scale) : black(make_shared<ColorMaterial>(Colors::Black)), white(make_shared<ColorMaterial>(Colors::White)) {
	this->scale = scale;
}

inline Color PerlinNoiseTexture::shade(const Scene * scene, const Ray & ray, const IntersectResult & intersect, const TraceState & traceState) const {
	Double value;
	switch (mapping) {
	case Texture::UV:
		value = stb_perlin_noise3(float(intersect.uv.x * scale.x + offset.x),
			float(intersect.uv.y * scale.y + offset.y), float(offset.z));
		break;
	case Texture::Position:
		value = stb_perlin_noise3(float(intersect.position.x * scale.x + offset.x),
			float(intersect.position.y * scale.y + offset.y),
			float(intersect.position.z * scale.z + offset.z));
		break;
	default:
		return Colors::Black;
	}
	value += 0.5;
	return lerp(black->shade(scene, ray, intersect, traceState), white->shade(scene, ray, intersect, traceState), value);
}
